package com.allen.app.common.utils;


import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.fasterxml.jackson.core.type.TypeReference;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
import java.util.Objects;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @Classname HttpHelper
 * @Description HttpHelper
 * @Date 2021/09/09 14:29
 * @Created by Limiaojun
 */
@Slf4j
public class HttpHelper extends HttpUtil {

    private final HttpProperties httpProperties;

    public HttpHelper(HttpProperties httpProperties) {
        this.httpProperties = httpProperties;
    }

    public String request(Method method, String uri, Object... param) {
        uri = builderUrl(uri, param);
        HttpRequest httpRequest = buildHttpRequest(method, uri, null, null);
        String result = httpRequest.execute().body();
        if (httpProperties.getIsPrintResultConsule()) {
            log.info(result);
        }
        return result;
    }

    public String requestQuery(Method method, String uri, Object paramMap, Object... param) {
        uri = builderUrl(uri, param);
        HttpRequest httpRequest = buildHttpRequest(method, uri, ParamType.QUERY, paramMap);
        String result = httpRequest.execute().body();
        if (httpProperties.getIsPrintResultConsule()) {
            log.info(result);
        }
        return result;
    }

    public String requestBody(Method method, String uri, Object objectParam, Object... param) {
        uri = builderUrl(uri, param);
        HttpRequest httpRequest = buildHttpRequest(method, uri, ParamType.BODY, objectParam);
        String result = httpRequest.execute().body();
        if (httpProperties.getIsPrintResultConsule()) {
            log.info(result);
        }
        return result;
    }

    protected String builderUrl(String uri, Object... param) {
//        Assert.notBlank(host, "host 不能为空");
        uri = httpProperties.host + uri.replaceAll("/+", "/");

        if (Objects.nonNull(param) && param.length > 0) {
            uri = String.format(uri, param);
        }
        return uri;
    }

    /**
     * 构建httpRequest对象,如不满足要求可继承并重写.
     *
     * @param method 方法类型
     * @param uri 接口地址
     * @param paramType paramType.QUERY.BODY
     * @param objectParam 请求参数(map or 对象)
     * @return cn.hutool.http.HttpRequest
     * @author Limiaojun
     * @date 2021/3/5 0005 09:16
     */
    protected HttpRequest buildHttpRequest(Method method, String uri, ParamType paramType, Object objectParam) {
        HttpRequest request = createRequest(method, uri);
        if (Objects.isNull(objectParam)) {
            return request;
        }
        if (Objects.isNull(paramType) || ParamType.QUERY == paramType) {
            request.form(Jackson.jsonObject(objectParam));
        } else if (ParamType.BODY == paramType) {
            request.body(Jackson.json(objectParam));
        }
        request.timeout(httpProperties.getTimeout());

        return request;
    }

    /**
     * 将json字符串转换为Bean的List，默认为ArrayList. 如果不传arrKey直接序列化jsonStr为JSONArray
     *
     * @param jsonStr json字符串
     * @param arrKey json字符串数组key
     * @return List
     * @since 4.0.7
     */
    public <T> List<T> toList(String jsonStr, String arrKey) {
        if (CheckObjectUtils.isNull(arrKey)) {
            return Jackson.object(jsonStr, new TypeReference<List<T>>() {
            });
        } else {
            return Jackson.object(Jackson.jsonObject(jsonStr).getString(arrKey), new TypeReference<List<T>>() {
            });
        }
    }

    public <T> T toObj(String jsonStr, Class<T> type) {
        return Jackson.object(jsonStr, type);
    }

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "microx.http-helper")
    @NoArgsConstructor
    @Accessors(chain = true)
    public static class HttpProperties {

        @ApiModelProperty(value = "http地址", dataType = "String")
        private String host = "";
        @ApiModelProperty(value = "超时时长", dataType = "Integer")
        private Integer timeout = 5000;
        @ApiModelProperty(value = "是否打印http返回日志", dataType = "Boolean")
        private Boolean isPrintResultConsule = false;
    }

    public enum ParamType {
        QUERY, BODY
    }


   /* public static void main(String[] args) {
        HttpHelper httpHelper = new HttpHelper(
            new HttpProperties()
                .setHost("http://172.16.10.196:10061")
                .setIsPrintResultConsule(true)
        );

        //格式化uri
        httpHelper.request(Method.GET,"url?id=%s&name=%s",1,2);
        //query参数,form提交
        httpHelper.request(Method.GET,"url", Maps.of("id",1));
        //body参数,格式化uri
        httpHelper.requestBody(Method.POST,"update?id=%s", Maps.of("id",1),1);

        //下载
        downloadFile("http://test-resource.food-see.com/v2/min_app/activity_image/activity/2020-06-03/lXbzI34G4f7zJ1YJQWnb.gif","D:\\tmp.gif");
        //上传
        String body = createPost("http://172.16.10.194:8082/v1/upload/product_image")
            .form("file", new File("D:\\tmp.gif")).execute().body();
    }*/
}
